﻿using System.ComponentModel;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;

namespace Job.Core.Web.UI
{
    /// <summary>
    /// Web 分页控件。
    /// web.config
    /// <pages>
    ///     <controls>
    ///         <add tagPrefix="asp" namespace="Job.Core.Web.UI" assembly="Job.Core"/>
    ///     </controls>
    /// </pages>
    /// </summary>
    [DefaultProperty("PageSplit"), ToolboxData("<{0}:PageSplit runat=server />")]
    public class PageSplit : System.Web.UI.WebControls.WebControl
    {
        #region Properties

        private int pageSize = 10;

        /// <summary>
        /// 每页显示记录数。
        /// </summary>
        [
        Bindable(true),
        DefaultValue(10),
        Description("PageSize")
        ]
        public int PageSize
        {
            get { return pageSize; }
            set { pageSize = value; }
        }

        private int pageIndex = 1;

        /// <summary>
        /// 当前页码。
        /// </summary>
        [
        Bindable(true),       
        DefaultValue(1),
        Description("PageIndex")
        ]
        public int PageIndex
        {
            get
            {
                int.TryParse(HttpContext.Current.Request.QueryString[splitName], out pageIndex);
                return pageIndex < 1 ? 1 : pageIndex;
            }
            set { pageIndex = value; }
        }

        private int recordCount;

        /// <summary>
        /// 总记录数。
        /// </summary>
        [
        Bindable(true),       
        DefaultValue(0),
        Description("RecordCount")
        ]
        public int RecordCount
        {
            get { return recordCount; }
            set { recordCount = value; }
        }

        private string splitName = "Page";

        /// <summary>
        /// 作为分页的参数名称。
        /// </summary>
        [
        Bindable(true),       
        DefaultValue("Page"),
        Description("SplitName")
        ]
        public string SplitName
        {
            get { return splitName; }
            set { splitName = value; }
        }

        private string urlRewrite = string.Empty;

        /// <summary>
        /// Url 重写(使用<参数名称>来维持当时前的参数值)。
        /// </summary>
        [
        Bindable(true),       
        DefaultValue(""),
        Description("UrlRewrite")
        ]
        public string UrlRewrite
        {
            get { return urlRewrite; }
            set { urlRewrite = value; }
        }        

        private static Regex paramRegex = new Regex(@"<\w+>", RegexOptions.Compiled);

        #endregion

        #region Methods

        /// <summary>
        /// 初始化 url。
        /// </summary>
        /// <returns>初始化后的 url 字串。</returns>
        private string InitUrl()
        {
            string url = string.Empty;

            if (!string.IsNullOrEmpty(urlRewrite))
            {

                MatchCollection coll = paramRegex.Matches(urlRewrite);
                url = urlRewrite;

                foreach (System.Text.RegularExpressions.Match m in coll)
                {
                    string getName = m.Value.Trim('<', '>');

                    if (string.Compare(getName, splitName, true) == 0)
                        url = url.Replace(m.Value, "{0}");
                    else
                        url = url.Replace(m.Value, HttpContext.Current.Request.QueryString[getName]);
                }
            }
            else
            {
                url = HttpContext.Current.Request.RawUrl;

                Regex reg = new Regex(splitName + @"=\w*", RegexOptions.IgnoreCase);
                if (reg.IsMatch(url))
                {
                    url = reg.Replace(url, splitName + "={0}");
                }
                else
                {
                    url += (url.IndexOf('?') == -1) ? "?" : "&";
                    url += splitName + "={0}";
                }
            }

            return url;
        }

        /// <summary>
        /// 将此控件呈现给指定的输出参数。
        /// </summary>
        /// <param name="writer">writer。</param>
        protected override void Render(HtmlTextWriter writer)
        {
            if (RecordCount == 0) return;          
            writer.Write(PageingHtml);
        }

        /// <summary>
        /// 获取需呈现 html 代码，可以子类重写此方法来实现不同的分页样式。
        /// </summary>
        /// <param name="baseUrl">经初始化的 url，url 的 {0} 位置为需替换的页码。 eg: /Index_{0}.html</param>
        /// <param name="pageIndex">当前页码。</param>
        /// <param name="pageSize">每页显示的记录数。</param>
        /// <param name="recordCount">总记录数。</param>
        /// <returns>最终需呈现的 html 字串。</returns>
        protected virtual string RenderHtml(string baseUrl, int pageIndex, int pageSize, int recordCount)
        {
            int pageCount = (recordCount % pageSize == 0) ? recordCount / pageSize : recordCount / pageSize + 1;

            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("<div{0}>", (string.IsNullOrEmpty(CssClass) ? string.Empty : " class=\"" + CssClass + "\""));

            sb.AppendFormat("<span class=\"disabled\">总记录 {2} 页码 {0}/{1}</span>", pageIndex, pageCount, recordCount);

            //上一页
            if (pageIndex > 1)
                sb.AppendFormat("<a target=\"_self\" href=\"{0}\"> < " + RS.GetString("Page_Prev") + "</a>", string.Format(baseUrl, pageIndex - 1));
            else
                sb.Append("<span class=\"disabled\"> < " + RS.GetString("Page_Prev") + "</span>");

            //前两页
            if (pageIndex > 3)
            {
                sb.AppendFormat("<a target=\"_self\" href=\"{0}\">1</a>", string.Format(baseUrl, 1));
                sb.AppendFormat("<a target=\"_self\" href=\"{0}\">2</a>", string.Format(baseUrl, 2));
                sb.Append("<span>..</span>");
            }

            //中间页数
            int start = pageIndex - 2;
            if (start < 1) start = 1;
            if (start == 2) start = 4;
            int end = start + 4;
            if (end > pageCount) end = pageCount;
            if (pageCount - end == 1) end -= 1;
            for (int i = start; i <= end; i++)
            {
                if (i == pageIndex)
                    sb.Append("<span class=\"current\">" + i + "</span>");
                else
                    sb.AppendFormat("<a target=\"_self\" href=\"{0}\">{1}</a>", string.Format(baseUrl, i), i);
            }

            //后两页
            if ((pageCount > 5) && (pageIndex + 2 < pageCount))
            {
                sb.Append("<span>..</span>");
                sb.AppendFormat("<a target=\"_self\" href=\"{0}\">{1}</a>", string.Format(baseUrl, pageCount - 1), (pageCount - 1));
                sb.AppendFormat("<a target=\"_self\" href=\"{0}\">{1}</a>", string.Format(baseUrl, pageCount), pageCount);
            }

            //下一页
            if (pageIndex < pageCount)
                sb.AppendFormat("<a target=\"_self\" href=\"{0}\">" + RS.GetString("Page_Next") + " > </a>", string.Format(baseUrl, pageIndex + 1));
            else
                sb.Append("<span class=\"disabled\">" + RS.GetString("Page_Next") + " > </span>");

            sb.Append("</div>");
            return sb.ToString();
        }



        /// <summary>
        /// 分页的html code。
        /// </summary>
        [
        Bindable(true),
        DefaultValue(""),
        Description("分页的html code")
        ]
        public string PageingHtml
        {
            get { return RenderHtml(InitUrl(), PageIndex, PageSize, RecordCount); }
        }
        #endregion
    }
}